# -*- coding: utf-8 -*-
import maya.cmds as cmds


def selected():
    sel = cmds.ls(sl=True)
    obj = sel[-1]
    objList = sel[:-1]
    meshShapeList = []
    pivList = []

    for i in objList:
        shapes = cmds.listRelatives(i, shapes=True)
        if shapes is None:
            meshShapeList.append(i)
        else:
            meshShapeList.append(shapes[0])

        # 获取物体的边界框，找到中心点
        minusX, minusY, minusZ, plusX, plusY, plusZ = cmds.exactWorldBoundingBox(i)
        x = (minusX + plusX) / 2.0
        y = (minusY + plusY) / 2.0
        z = (minusZ + plusZ) / 2.0
        positionValue = [x, y, z]
        pivList.append(positionValue)

    getClosePOMInfo(pivList, meshShapeList, obj)


def getClosePOMInfo(pivList, meshShapeList, obj):
    RivetGrp = []
    objShape = cmds.listRelatives(obj, shapes=True)[0]

    if cmds.nodeType(objShape) == 'mesh':
        pomNode = cmds.createNode('closestPointOnMesh', n="cur_closePOM")
        cmds.connectAttr(obj + '.outMesh', pomNode + '.inMesh', f=True)
        cmds.connectAttr(obj + '.worldMatrix[0]', pomNode + '.inputMatrix', f=True)

    elif cmds.nodeType(objShape) == 'nurbsSurface':
        # """
        # closestPointOnSurface转换UV值解决办法参考mel插件djRivet
        # 作者：
        # David Johnson
        # david@djx.com.au
        # https://www.djx.com.au/blog
        # """
        # closestPointOnSurface ignores surface transforms,
        # so we need make a temporary copy and freeze the transforms
        # (make sure transform channels are not locked)
        pomNode = cmds.createNode('closestPointOnSurface', n='cur_closePOSur')
        objDup = cmds.duplicate(obj, n=obj+'_dup')[0]
        cmds.makeIdentity(objDup, apply=True, n=1, pn=True)
        transform = cmds.createNode('transform', n='transform') #

        cmds.connectAttr(objDup + '.local', pomNode + '.inputSurface', f=True)
        cmds.connectAttr(transform + '.translate', pomNode + '.inPosition', f=True)
    else:
        return cmds.error(u'只能钉在mesh或者nurbsSurface表面')

    for piv, meshShape in zip(pivList, meshShapeList):

        follicleShape = cmds.createNode('follicle')
        follicle = cmds.listRelatives(follicleShape, p=True)[0]
        cmds.setAttr(follicleShape + '.simulationMethod', 0)
        RivetGrp.append(follicle)

        # 判断是closestPointOnMesh还是closestPointOnSurface节点
        if cmds.nodeType(pomNode) == 'closestPointOnMesh':
            cmds.setAttr(pomNode + '.inPosition', piv[0], piv[1], piv[2])
            cmds.connectAttr(objShape+'.outMesh', follicleShape+'.inputMesh', f=True)
            cmds.connectAttr(objShape+'.worldMatrix[0]', follicleShape+'.inputWorldMatrix', f=True)
            # position = cmds.getAttr(pomNode + ".result.position") ###
            pivU = cmds.getAttr(pomNode + ".result.parameterU")
            pivV = cmds.getAttr(pomNode + ".result.parameterV")
            # vtxIndex = cmds.getAttr(pomNode + ".result.closestVertexIndex")
        else:
            cmds.xform(transform, ws=True, t=[piv[0], piv[1], piv[2]])
            cmds.connectAttr(objShape+'.local', follicleShape+'.inputSurface', f=True)
            cmds.connectAttr(objShape+'.worldMatrix[0]', follicleShape+'.inputWorldMatrix', f=True)

            minMaxRangeU = cmds.getAttr(objDup + '.minMaxRangeU')[0]
            minMaxRangeV = cmds.getAttr(objDup + '.minMaxRangeV')[0]

            parameterU = cmds.getAttr(pomNode + '.parameterU')
            parameterV = cmds.getAttr(pomNode + '.parameterV')

            pivU = abs((parameterU - minMaxRangeU[0]) / (minMaxRangeU[1] - minMaxRangeU[0]))
            pivV = abs((parameterV - minMaxRangeV[0]) / (minMaxRangeV[1] - minMaxRangeV[0]))

            cmds.delete(transform, objDup)

        cmds.connectAttr(follicleShape+'.outTranslate', follicle+'.translate', f=True)
        cmds.connectAttr(follicleShape+'.outRotate', follicle+'.rotate', f=True)

        cmds.setAttr(follicleShape + '.parameterU', pivU)
        cmds.setAttr(follicleShape + '.parameterV', pivV)

        # 判断选择的物体类型，parent约束
        if cmds.nodeType(meshShape) == 'mesh' or \
            cmds.nodeType(meshShape) == 'locator' or \
            cmds.nodeType(meshShape) == 'nurbsCurve' or \
            cmds.nodeType(meshShape) == 'nurbsSurface':

            mesh = cmds.listRelatives(meshShape, parent=True)
            cmds.parentConstraint(follicle, mesh, mo=True)
        else:
            cmds.parentConstraint(follicle, meshShape, mo=True)

    cmds.delete(pomNode)
    # 判断场景中是否有Rivet_Grp组
    ls = [ls for ls in cmds.ls(type='transform') if ls == 'Rivet_Grp']
    if len(ls) > 0 and ls[0] == 'Rivet_Grp':
        cmds.parent(RivetGrp, 'Rivet_Grp')
    else:
        grp = cmds.group(RivetGrp, n='Rivet_Grp')
        cmds.setAttr(grp + '.tx', lock=True, keyable=False, channelBox=False)
        cmds.setAttr(grp + '.ty', lock=True, keyable=False, channelBox=False)
        cmds.setAttr(grp + '.tz', lock=True, keyable=False, channelBox=False)
        cmds.setAttr(grp + '.rx', lock=True, keyable=False, channelBox=False)
        cmds.setAttr(grp + '.ry', lock=True, keyable=False, channelBox=False)
        cmds.setAttr(grp + '.rz', lock=True, keyable=False, channelBox=False)
        cmds.setAttr(grp + '.sx', lock=True, keyable=False, channelBox=False)
        cmds.setAttr(grp + '.sy', lock=True, keyable=False, channelBox=False)
        cmds.setAttr(grp + '.sz', lock=True, keyable=False, channelBox=False)
        cmds.setAttr(grp + '.v', 1, lock=True)
